function sdkChangeSingle( cmd, cellID, candidID){
	return {
		cmd: cmd,
		cellID:cellID,
		candidID: candidID,
		exec: function( slice){
			slice=sdkSlice( slice.concat());
			var a = slice.filterByID( cellID);
			switch( cmd){
				case "swap":
					a=a.swap( candidID, true);
					break;
				case "only":
					a=a.only( candidID, true);
					break;
				case "disable":
					a=a.disable( candidID, true);
					break;
				case "enable":
					a=a.enable( candidID, true);
					break;
				default:
					throw "Unknown command for sdkChange: "+ cmd;
			}
			a=a.concat( slice.filterNotID(cellID));
			return sdkSlice(a);
		},
		add: function( arr){
			return [this, arr];
		},
		id : function(){
			return cmd+cellID+candidID;
		}
	};
}

var sdkChange = Object.extend(function sdkChangeFn( arg){
	if( arguments.length > 1){
		return sdkChangeSingle.apply(undefined, arguments);
	} else {
		if( !arg){
			arg = [];
		}
		arg.exec = function( arr){
			arr = arr.concat();
			this.forEach(function( elem){
				arr= elem.exec(arr);
			});
			return arr;
		};
		arg.add = function( arr){
			return sdkChange( this.concat( arr));
		};
		arg.id = function(){
            return this.map(function(elem){
                return elem.id();
            }).join("");
		};

		return arg;
	}
},{
	unique: function( arr){
		var newArr= [],
			ids= {};
			
		for( var i=0; i< arr.length; i++){
			if( arr[i] !== undefined && !ids[ arr[i].id()] ){
				newArr.push( arr[i]);
				ids[ arr[i].id()]=true;
			}
		}
		
		return sdkChange( newArr);
	}
});
